package com.bryant.bryant_weather.utils

import com.bryant.bryant_weather.WeatherApplication
import com.bryant.bryant_weather.apis.ApiService
import com.bryant.bryant_weather.storage.TokenPreferences
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

object RetrofitClient {
    // 1. 定义基础Url常量
    // 对于像 BASE_URL 这样的基础配置常量，使用 const 是最佳实践
    // 因为它提供了更好的性能并且明确表达了这是一个不可变的编译时常量
    private const val BASE_URL = "http://192.168.1.101:3000"

    // ------------- 添加拦截器 -----------------
    private val okHttpClientInstance: OkHttpClient by lazy {
        // 1. 创建 okHttpClient 实例， 用于发送http请求
        OkHttpClient.Builder()
            // 添加拦截器
            .addInterceptor(AuthInterceptor())
            // 添加日志拦截器
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY// 打印完整的请求和响应内容
            })
            // 设置连接超时时间：30 秒
            .connectTimeout(30, TimeUnit.SECONDS)
            // 设置读取超时时间：30 秒
            .readTimeout(30, TimeUnit.SECONDS)
            // 构建并返回最终的 OkHttpClient 对象
            .build()
    }

    // ------------------ Token拦截器 --------------------
    // Token 拦截器
    private class AuthInterceptor : Interceptor {
        override fun intercept(chain: Interceptor.Chain): Response {
            // 1. 获取本地网络请求对象（请求体）
            val request = chain.request()

            // 从 TokenPreferences 中获取存储的 token，用于身份验证
            val authToken = TokenPreferences.getInstance(
                WeatherApplication.getInstance().applicationContext
            ).getToken()

            // 使用安全的空值处理方式判断 token 是否存在
            val newRequest = authToken?.let { token ->
                // 如果 token 存在，则构建新的请求对象，并添加 Authorization 头部
                request.newBuilder()
                    .header("Authorization", "Bearer $token") // 添加 Bearer Token 到请求头，用于身份验证
                    .build()
            } ?: request // 如果 token 不存在，则继续使用原始请求对象

            // 继续执行请求链，并返回响应结果
            return chain.proceed(newRequest)
        }
    }

    // 2. 使用延迟初始化， 确保在第一次需要使用AppService时才创建实例，避免资源浪费
    val apiService:ApiService by lazy{
        // 1. 创建Retrofit构建起
        Retrofit.Builder()
            .client(okHttpClientInstance)
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiService::class.java)
    }
}